<?php
namespace Tbf\Component\Arrays;

/**
 * 使用bit hack方法储存一个boolean的数组,下标从0开始
 * 下标越界抛出异常
 * 优势:节约内存
 * 不用进行cpu缓存优化,指令顺序优惠之类的,反正是解释执行...
 */
class BitBooleanArray {
    /**
     * @var string
     */
    protected $data;
    /**
     * @var integer
     */
    protected $len;
    function __construct($len){
        $this->data = str_repeat("\x00",ceil($len/8));
        $this->len = $len;
    }
    function get($i){
        if ($i >= $this->len){
            throw new \Exception(sprintf('array index greater then bound i:%d, len:%d',$i,$this->len));
        }
        if ($i < 0){
            throw new \Exception('array index less then 0');
        }
        return (boolean)((ord($this->data[(int)floor($i/8)]) >> $i%8) & 1);
    }
    function set($i,$value){
        if ($i >= $this->len){
            throw new \Exception(sprintf('array index greater then bound i:%d, len:%d',$i,$this->len));
        }
        if ($i < 0){
            throw new \Exception('array index less then 0');
        }
        $string_index = (int)floor($i/8);
        if ($value===true){
            $this->data[$string_index] = chr(ord($this->data[$string_index]) | (1 << $i%8));
        }elseif($value===false){
            $this->data[$string_index] = chr(ord($this->data[$string_index]) & (~(1 << $i%8)));
        }else{
            throw new \Exception('BitBooleanArray only accept true and false');
        }
    }
}